//TODO: License Header.

/*
This code is licensed under the BSD license.

*/
package analysis.metrics

import primitives.cluster.ClusterHead
import primitives.graph.Node
import search.util.TreeLoader2
import static Math.min
import primitives.cluster.*;
import primitives.graph.*;

class ClusteringCoefficientMetric /* extends Metric */{
	
	static def neighbours(Node n,ClusterHead tree){
		def ins = tree.nodes.findAll{
			it.pathTo(n) && it!=n
		}
		def outs = n.transitionsAsN
		
		return outs
		
	}
	
	static def any(elements){
		return elements.find{it == true} != null;
	}
	
	static def neighbour(Node n,Node m){
		return n.pathTo(m) || m.pathTo(n);
	}

	static def degree(Node n, ClusterHead tree){
		def ins = tree.nodes.findAll({
			node ->
			node.pathTo(n) && node != n
		}).collect{
			t ->
			t.transitionsAsT.findAll{it.destinationNode == n}
		}.flatten();
		
		def outs= n.transitionsAsT
		
		//def degree = ([ins,outs].collect{it.size()}.sum(0))
		
		def degree = outs
		
		if(degree in [0,1]) return degree;
		
		def S = neighbours(n,tree)
		
		if(S.size() in [0,1]) return S.size();
		
		def len_w = S.findAll{
			w ->
			any(w.transitionsAsN.collect{
				it in S
			})
		}.size()
		
		return (len_w / (S.size() * (S.size() - 1) / 2))
		
	}
	
	static def evaluate(ClusterHead tree){
		return tree.nodes.collect{
			[it,degree(it,tree)]
		}

	}
	
	@Deprecated
	public static void main(String[] args){
		def filename = args[0]

		ClusterHead tree = TreeLoader2.loadTreeFromSerial(new File(filename))
		evaluate(tree).each{
			result ->
			def(intra,extra) = result;
			intra = intra.label
			//println("N[$intra] E[$extra]")
		};

		


		
	}
	
}